package com.openlogic.common.core.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson2.JSON;
import com.openlogic.common.core.json.JSONUtil;


/**
* @ClassName: ConvertUtils
* @Description: 类型转换工具类
* @author weiyongpeng
* @date 2025年1月13日 上午9:35:56
 */
public class ConvertUtil {

	private static final Logger log = LoggerFactory.getLogger(ConvertUtil.class);

	/**
	* @ClassName: Type
	* @Description: 类型转化枚举类型
	* @author weiyongpeng
	* @date 2024年5月22日 上午11:40:23
	 */
	public enum Type {
		BOOLEAN(new String[] { "boolean", "java.lang.boolean" }), STRING(new String[] { "string", "java.lang.string" }),
		INT(new String[] { "int", "integer", "java.lang.integer" }), LONG(new String[] { "long", "java.lang.long" }),
		BIGINT(new String[] { "bigint", "biginteger", "java.math.biginteger" }),
		DOUBLE(new String[] { "double", "java.lang.double" }), DATE(new String[] { "date", "java.util.date" }),
		SQLDATE(new String[] { "sqldate", "java.sql.date" }),
		TIMESTAMP(new String[] { "timestamp", "java.sql.timestamp" }), MAP(new String[] { "map" }),
		LIST(new String[] { "list" }), DECIMAL(new String[] { "decimal", "java.math.bigdecimal" });

		private String[] names;

		private Type(String[] names) {
			this.names = names;
		}

		/**
		* 描述：对应类型转化为枚举类型
		* @Title: parseType
		* @param name ：boolean -> Type.Boolean
		* @return
		* @author weiyongpeng
		* @date  2024年5月22日 上午11:41:12
		 */
		public static Type parseType(String name) {
			if (name != null) {
				name = name.toLowerCase();
			}
			for (Type type : Type.values()) {
				for (String tname : type.names) {
					if (tname.equals(name)) {
						return type;
					}
				}
			}
			return null;
		}

		/**
		* 描述：对应类型转化为枚举类型
		* @Title: parseType
		* @param clz Boolean.class -> Type.Boolean
		* @return
		* @author weiyongpeng
		* @date  2024年5月22日 上午11:40:49
		 */
		public static Type parseType(Class<Type> clz) {
			if (clz == null) {
				return null;
			}
			return parseType(clz.getName());
		}
	}

	/**
	* 描述：String: 类型转化为对应包装类
	* @Title: convert
	* @param toType String类型的 boolean
	* @param value
	* @return
	* @author weiyongpeng
	* @date  2024年5月22日 上午11:32:41
	 */
	public static Object convert(String toType, String value) {
		Type type = Type.parseType(toType);
		if (type == null) {
			throw new RuntimeException("unsupport type : " + toType);
		}
		return convert(type, value);
	}
	
	/**
	* 描述：String；类型转化为对应包装类
	* @Title: convert
	* @param toType Type枚举类型 Type.Boolean 
	* @param value
	* @return
	* @author weiyongpeng
	* @date  2024年5月22日 上午11:30:27
	 */
	public static Object convert(Class<Type> toType, String value) {
		if (toType != null && toType.isEnum()) {
			try {
				return Enum.valueOf(toType, value);
			} catch (Exception e) {
				log.error("异常信息：[{}]", e);
			}
		}

		Type type = Type.parseType(toType);
		if (type == null) {
			throw new RuntimeException("unsupport type : " + toType);
		}
		return convert(type, value);
	}

	/**
	* 描述：String；类型转化为对应包装类
	* @Title: convert
	* @param toType
	* @param value
	* @return
	* @author weiyongpeng
	* @date  2024年5月22日 上午11:29:11
	 */
	public static Object convert(Type toType, String value) {
		CheckUtil.notNull(toType, "toType");
		if (Type.STRING.equals(toType)) {
			return value;
		}
		if (CheckUtil.isEmpty(value)) {
			return null;
		}
		switch (toType) {
		case INT:
			return Integer.parseInt(value);
		case LONG:
			return Long.parseLong(value);
		case BIGINT:
			return new BigInteger(value);
		case DOUBLE:
			return Double.parseDouble(value);
		case DATE: {
			try {
				return DateUtils.parseDate(value,
						new String[] { DateUtils.DATE_FORMAT_DATEONLY, DateUtils.DATE_FORMAT_DATETIME });
			} catch (ParseException e) {
				throw new RuntimeException(e.getMessage(), e);
			}
		}
		case SQLDATE: {
			try {
				return new java.sql.Date(DateUtils.parseDate(value, DateUtils.DATE_FORMAT_DATEONLY).getTime());
			} catch (Exception e) {
				throw new RuntimeException(e.getMessage(), e);
			}
		}
		case TIMESTAMP: {
			try {
				return new java.sql.Timestamp(DateUtils.parseDate(value, DateUtils.DATE_FORMAT_DATETIME).getTime());
			} catch (Exception e) {
				throw new RuntimeException(e.getMessage(), e);
			}
		}
		case BOOLEAN:
			return Boolean.parseBoolean(value);
		case DECIMAL:
			return new BigDecimal(value);
		case MAP: {
			return JSONUtil.jsonToMap(value, String.class, String.class);
		}
		case LIST: {
			return JSONUtil.jsonToList(value, String.class);
		}
		default:
			throw new RuntimeException("unsupport type : " + toType);
		}
	}

	
	/**
	 * 描述：对象转List
	 * @Title: objToList
	 * @param <T>
	 * @param obj
	 * @param cla
	 * @return
	 * @throws Exception
	 * @author weiyongpeng
	 * @date 2024年5月22日 上午10:32:30
	 */
	public static <T> List<T> objToList(Object obj, Class<T> cla) {
		try {
			List<T> list = new ArrayList<T>();
			if (obj instanceof ArrayList<?>) {
				for (Object o : (List<?>) obj) {
					list.add(JSON.parseObject(JSON.toJSONString(o), cla));
				}
				return list;
			}
		} catch (Exception e) {
			log.error("类型转化异常:[{}]", e);
		}
		return null;
	}

	/**
	* 描述：对象转化为Map
	* @Title: objToMap
	* @param obj
	* @return
	* @author weiyongpeng
	* @date  2024年5月22日 上午11:23:59
	 */
	public static Map<String, Object> objToMap(Object obj) {
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			Field[] fields = obj.getClass().getDeclaredFields();
			for (Field field : fields) {
				field.setAccessible(true);
				map.put(field.getName(), field.get(obj));
			}
		} catch (Exception e) {
			log.error("类型转化异常:[{}]", e);
			return null;
		} 
		return map;
	}

	/**
	* 描述：map转化为Object
	* @Title: mapToObj
	* @param map
	* @param clz
	* @return
	* @author weiyongpeng
	* @date  2024年5月22日 上午11:21:56
	 */
	public static Object mapToObj(Map<String, Object> map, Class<?> clz) {
		Object obj;
		try {
			obj = clz.getDeclaredConstructor().newInstance();
			Field[] declaredFields = obj.getClass().getDeclaredFields();
			for (Field field : declaredFields) {
				int mod = field.getModifiers();
				if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
					continue;
				}
				field.setAccessible(true);
				field.set(obj, map.get(field.getName()));
			}
			return obj;
		} catch (Exception e) {
			log.error("类型转化异常:[{}]", e);
		} 
		return null;
	}

}
